package perceptronStephane;

public class PerceptronXORXp implements ISAESXp
{
	final OneLayerPerceptron perceptron;
	
	public PerceptronXORXp()
	{
		this.perceptron = new OneLayerPerceptron(2, 1, 2);
	}
	
	public int getDimension() 
	{
		return 3 * 2 + 2 * 1;
	}

	public double getFitness(double[] vector) 
	{
		this.setVector(vector);
		
		double fitness = 0;
		
		fitness += deltaXOR(false, false);
		fitness += deltaXOR(false, true);
		fitness += deltaXOR(true, false);
		fitness += deltaXOR(true, true);
		
		return fitness;
	}
	
	public void setFinalVector(double[] vector) {
		this.setVector(vector);
		
	}
	
	private void setVector(double[] vector)
	{
		int offset = 0;
		for(int i = 0; i < 2; i++)
		{
			for(int j = 0; j < 3; j++)
			{
				double weight = vector[offset];
				this.perceptron.setInLinkWeight(j, i, weight);
				offset++;
			}
		}

		for(int i = 0; i < 2; i++)
		{
			for(int j = 0; j < 1; j++)
			{
				double weight = vector[offset];
				this.perceptron.setOutLinkWeight(j, i, weight);
				offset++;
			}
		}
		
	}
	
	private double deltaXOR(boolean x, boolean y)
	{
		perceptron.setInNodeWeight(0, x?1:0);
		perceptron.setInNodeWeight(1, y?1:0);
		
		perceptron.activate();
		
		double delta = Math.abs(perceptron.getOutWeight(0) - ((x ^ y)?1:0));
		
		return delta * delta;
	}
	
	public boolean testXOR(boolean x, boolean y)
	{
		perceptron.setInNodeWeight(0, x?1:0);
		perceptron.setInNodeWeight(1, y?1:0);
		
		perceptron.activate();
		
		return ((perceptron.getOutWeight(0)<0.5)?false:true) == (x ^ y);		
	}

	@Override
	public String toString() {

		return this.perceptron.toString();
	}
	
	
}
